package com.tju.backend.plugin.t_io_server;

import com.tju.backend.plugin.common.AbsCommonAioHandler;
import com.tju.backend.plugin.common.SPPacket;
import com.tju.backend.plugin.common.Type;
import com.tju.backend.plugin.common.intf.AbsCommonBsHandler;
import com.tju.backend.plugin.t_io_server.handler.AgvData;
import com.tju.backend.plugin.t_io_server.handler.CoreBandDispose;
import com.tju.backend.plugin.t_io_server.handler.PlcSignal;
import com.tju.backend.utils.tool.Constants;
import com.tju.backend.utils.tool.EmptyUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.tio.core.ChannelContext;
import org.tio.core.intf.Packet;
import org.tio.server.intf.ServerAioHandler;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * 处理消息 获取消息处理类
 *
 * @USER: CLS
 */
@Slf4j
@Component
public class SPServerAioHandler extends AbsCommonAioHandler implements ServerAioHandler {

    //定义处理类map
    private static final Map<Byte, AbsCommonBsHandler> handlerMap = new HashMap<>();

    static {
        handlerMap.put(Type.SYMBOL_REQ, new CoreBandDispose());//业务处理
        handlerMap.put(Type.SYMBOL_PLC, new PlcSignal());//业务处理
        handlerMap.put(Type.SYMBOL_AGV, new AgvData());//业务处理
    }

    /**
     * 处理消息
     */
    @Override
    public void handler(Packet packet, ChannelContext channelContext) throws Exception {
        SPPacket spPacket = (SPPacket) packet;
        //根据请求类型获取处理类
        AbsCommonBsHandler showcaseBsHandler = getHandler(spPacket);
        if (EmptyUtils.isNotEmpty(showcaseBsHandler))
            showcaseBsHandler.handler(spPacket, channelContext);
    }

    /**
     * 判断处理类
     */
    private AbsCommonBsHandler getHandler(SPPacket spPacket) {
        String content = new String(spPacket.getBody());
        System.err.println();
        if (content.startsWith(Constants.CMSHL)) {
            //相机信号
            return handlerMap.get(Type.SYMBOL_REQ);
        } else if (content.startsWith(Constants.AGV)) {
            return handlerMap.get(Type.SYMBOL_AGV);
        } else {
            //PLC信号
            return handlerMap.get(Type.SYMBOL_PLC);
        }
    }

    static long dataTime = 0;

    /**
     * 指令过滤
     */
    public boolean directLeach() {
        return Optional.ofNullable(dataTime)
                //验证当前数据时间是否是通讯启动开始的第一条指令
                .filter(i -> (dataTime != 0))
                .map(s -> {
                    //当前时间的时间戳
                    return System.currentTimeMillis();
                })
                .filter(c->!((c - dataTime) >= 1 && (c - dataTime) <= 1000))
                //不是第一次就开始过滤
                .map(s -> {
                    //当前时间的时间戳
                    long currentDate = System.currentTimeMillis();
                    if (!((currentDate - dataTime) >= 1 && (currentDate - dataTime) <= 1000)) {
                        dataTime = System.currentTimeMillis();
                        return "ok";
                    } else {
                        log.warn("过滤当前指令，和上次的间隔为 {}ms", (currentDate - dataTime));
                        dataTime = System.currentTimeMillis();
                        return "on";
                    }
                })
                //为第一条指令直接赋值
                .orElseGet(() -> {
                    //时间戳赋值
                    dataTime = System.currentTimeMillis();
                    log.info("第一次收到指令时间点 {}", org.tio.utils.hutool.DateUtil.formatDateTime(new Date()));
                    return "ok";
                }).equals("ok");
    }

}
